package com.fhyc.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fhyc.common.XPage;
import com.fhyc.dao.*;
import com.fhyc.dto.FhCompareDTO;
import com.fhyc.entity.*;
import com.fhyc.service.SoInFhCompareService;
import com.fhyc.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * (SoInFhCompare)表服务实现类
 *
 * @author makejava
 * @since 2024-10-14 09:01:14
 */
@Slf4j
@Service("soInFhCompareService")
public class SoInFhCompareServiceImpl implements SoInFhCompareService {
    @Resource
    private SoInFhCompareDao soInFhCompareDao;

    @Resource
    private SoInAreaDao soInAreaDao;

    @Resource
    private SoInTeamDao soInTeamDao;

    @Resource
    private SoInFhLoadForecastDao soInFhLoadForecastDao;

    @Resource
    private SoInFhLoadInfoXtDao soInFhLoadInfoXtDao;

    @Resource
    private SoInFhLoadInfoTdDao soInFhLoadInfoTdDao;

    @Override
    public XPage<SoInFhCompare> dailyLoadComparison1(Integer pageNum, Integer pageSize, LocalDate localDate, String areaId, Integer loadTypeId, List<Integer> teamIds, String batch) {
        LocalDate today = LocalDate.now(); // 获取今天的日期
        List<SoInFhCompare> records = new ArrayList<>();
        if (!CollectionUtils.isEmpty(teamIds)) {
            for (Integer i : teamIds) {
                QueryWrapper<SoInLoadForecast> forecastWrapper = new QueryWrapper<>();
                double sum = 0.0;
                double max = Double.NEGATIVE_INFINITY;
                double min = Double.POSITIVE_INFINITY;
                double avg = 0.0;
                Date maxTime = null;
                Date minTime = null;
                int count = 0;
                String teamName = null;
                SoInTeam team = soInTeamDao.selectById(i);
                if (team != null) {
                    teamName = team.getTeamName();
                }
                forecastWrapper.eq("YCCJ", teamName);
                forecastWrapper.eq("QYID", areaId);
                LocalDateTime startOfDay = localDate.atStartOfDay(); // 2024-10-30 00:00:00
                LocalDateTime endOfDay = localDate.atTime(23, 59, 59); // 2024-10-30 23:59:59
                forecastWrapper.ge("YCRQ", startOfDay)
                        .le("YCRQ", endOfDay);
                List<SoInLoadForecast> forecastList = soInFhLoadForecastDao.selectList(forecastWrapper);

                SoInFhCompare compare = new SoInFhCompare();
                SoInArea area = soInAreaDao.selectById(areaId);
                compare.setQyName(area.getCtrlAreaName());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String formattedDate = localDate.format(formatter);
                compare.setDataDate(formattedDate);
                compare.setYccj(teamName);

                if (loadTypeId == 1) {
                    // 获取当天的实际负荷数据
                    QueryWrapper<SoInLoadInfoXt> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", startOfDay)
                            .le("FHSJ", endOfDay);
                    List<SoInLoadInfoXt> loadInfoList = soInFhLoadInfoXtDao.selectList(infoXtWrapper);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    double totalRelativeError = 0.0;
                    int errorCount = 0;
                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;

                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }

                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoXt> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }
                    }

                    if (count > 0) {
                        avg = sum / count;
                        BigDecimal bigDecimal = new BigDecimal(avg);
                        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP); // 四舍五入
                        avg = bigDecimal.doubleValue();
                    } else {
                        max = 0.0;  // 修改此处：当无数据时，max 设为 0.0
                        min = 0.0;
                    }
                    compare.setAvgFh(avg);
                    // 计算平均准确率
                    double accuracyRate = 0.0;
                    if (errorCount > 0) {
                        accuracyRate = (1 - (totalRelativeError / errorCount)) * 100;
                        DecimalFormat df = new DecimalFormat("#.00");
                        accuracyRate = Double.parseDouble(df.format(accuracyRate)); // 保留两位小数
                    }

                    compare.setQyid(areaId);
                    compare.setYccj(teamName);
                    Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
                    compare.setYcrq(date);

                    compare.setAccuracy(accuracyRate);

                    compare.setMaxFh(max);
                    compare.setMinFh(min);
                    compare.setMaxFhTime(maxTime);
                    compare.setMinFhTime(minTime);
                    records.add(compare);
                }
                if (loadTypeId == 2) {
                    QueryWrapper<SoInLoadInfoTd> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", startOfDay)
                            .le("FHSJ", endOfDay);
                    List<SoInLoadInfoTd> loadInfoList = soInFhLoadInfoTdDao.selectList(infoXtWrapper);

                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    double totalRelativeError = 0.0;
                    int errorCount = 0;
                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;

                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }

                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoTd> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }
                    }

                    if (count > 0) {
                        avg = sum / count;
                        BigDecimal bigDecimal = new BigDecimal(avg);
                        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP); // 四舍五入
                        avg = bigDecimal.doubleValue();
                    } else {
                        max = 0.0;  // 修改此处：当无数据时，max 设为 0.0
                        min = 0.0;
                    }
                    compare.setAvgFh(avg);
                    // 计算平均准确率
                    double accuracyRate = 0.0;
                    if (errorCount > 0) {
                        accuracyRate = (1 - (totalRelativeError / errorCount)) * 100;
                        DecimalFormat df = new DecimalFormat("#.00");
                        accuracyRate = Double.parseDouble(df.format(accuracyRate)); // 保留两位小数
                    }

                    compare.setQyid(areaId);
                    compare.setYccj(teamName);
                    Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
                    compare.setYcrq(date);

                    compare.setAccuracy(accuracyRate);

                    compare.setMaxFh(max);
                    compare.setMinFh(min);
                    compare.setMaxFhTime(maxTime);
                    compare.setMinFhTime(minTime);
                    records.add(compare);
                }
            }

        }

        // 手动分页逻辑
        int total = records.size();
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        List<SoInFhCompare> pagedList = Collections.emptyList();
        if (fromIndex <= total && fromIndex < toIndex) {
            pagedList = records.subList(fromIndex, toIndex);
        }
        XPage<SoInFhCompare> info = new XPage<>();
        info.setRecords(pagedList);
        info.setPages(pageNum);
        info.setSize(pageSize);
        info.setTotal(records.size());
        return info;
    }

    @Override
    public XPage<SoInFhCompare> dailyLoadComparison10(Integer pageNum, Integer pageSize, LocalDate startTime, LocalDate endTime, String areaId, Integer loadTypeId, List<Integer> teamIds, String batch) {
        List<SoInFhCompare> records = new ArrayList<>();
        // 遍历从 startTime 到 endTime 的每一天
        LocalDate currentDate = startTime;
        while (!currentDate.isAfter(endTime)) {
            // 对每一天执行处理逻辑
            List<SoInFhCompare> dailyRecords = processDay(loadTypeId, currentDate, areaId, teamIds);
            if (!CollectionUtils.isEmpty(dailyRecords)) {
                records.addAll(dailyRecords);
            }
            // 日期递增一天
            currentDate = currentDate.plusDays(1);
        }

        // 手动分页逻辑
        int total = records.size();
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        List<SoInFhCompare> pagedList = Collections.emptyList();
        if (fromIndex <= total && fromIndex < toIndex) {
            pagedList = records.subList(fromIndex, toIndex);
        }

        XPage<SoInFhCompare> info = new XPage<>();
        info.setRecords(pagedList);
        info.setPages(pageNum);
        info.setSize(pageSize);
        info.setTotal(total);
        return info;

    }

    private List<SoInFhCompare> processDay(Integer loadTypeId, LocalDate date, String areaId, List<Integer> teamIds) {
        List<SoInFhCompare> dayRecords = new ArrayList<>();
        if (!CollectionUtils.isEmpty(teamIds)) {
            for (Integer i : teamIds) {
                QueryWrapper<SoInLoadForecast> forecastWrapper = new QueryWrapper<>();
                double sum = 0.0;
                //double max = 0.0;
                double max = Double.NEGATIVE_INFINITY;
                //double min = 0.0;
                double min = Double.POSITIVE_INFINITY;
                double avg = 0.0;

                double accuracyRate = 0.0;
                Date maxTime = null;
                Date minTime = null;
                int count = 0;
                String teamName = null;

                SoInTeam team = soInTeamDao.selectById(i);
                if (team != null) {
                    teamName = team.getTeamName();
                }

                forecastWrapper.eq("YCCJ", teamName);
                forecastWrapper.eq("QYID", areaId);
                forecastWrapper.ge("YCRQ", date.atStartOfDay())
                        .le("YCRQ", date.atTime(23, 59, 59));

                List<SoInLoadForecast> forecastList = soInFhLoadForecastDao.selectList(forecastWrapper);

                // 使用 SimpleDateFormat 来格式化时间做字符串比较
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SoInFhCompare compare = new SoInFhCompare();

                double totalRelativeError = 0.0;
                int errorCount = 0;
                if (loadTypeId == 1) {
                    // 获取当天的实际负荷数据
                    QueryWrapper<SoInLoadInfoXt> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", date.atStartOfDay())
                            .le("FHSJ", date.atTime(23, 59, 59));
                    List<SoInLoadInfoXt> loadInfoList = soInFhLoadInfoXtDao.selectList(infoXtWrapper);

                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;
                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }

                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoXt> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }

                        // 计算平均准确率
                        if (errorCount > 0) {
                            accuracyRate = (1 - (totalRelativeError / errorCount)) * 100;
                            DecimalFormat df = new DecimalFormat("#.00");
                            accuracyRate = Double.parseDouble(df.format(accuracyRate)); // 保留两位小数
                        }
                        //compare.setAccuracy(accuracyRate);
                    }
                }
                if (loadTypeId == 2) {
                    QueryWrapper<SoInLoadInfoTd> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", date.atStartOfDay())
                            .le("FHSJ", date.atTime(23, 59, 59));
                    List<SoInLoadInfoTd> loadInfoList = soInFhLoadInfoTdDao.selectList(infoXtWrapper);

                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;
                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }

                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoTd> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }

                        // 计算平均准确率
                        if (errorCount > 0) {
                            accuracyRate = (1 - (totalRelativeError / errorCount)) * 100;
                            DecimalFormat df = new DecimalFormat("#.00");
                            accuracyRate = Double.parseDouble(df.format(accuracyRate)); // 保留两位小数
                        }
                        //compare.setAccuracy(accuracyRate);
                    }
                }

                if (count > 0) {
                    avg = sum / count;
                    BigDecimal bigDecimal = new BigDecimal(avg).setScale(2, RoundingMode.HALF_UP);
                    avg = bigDecimal.doubleValue();
                } else {
                    avg = 0.0;
                    max = 0.0;
                    min = 0.0;
                }

                compare.setAccuracy(accuracyRate);
                compare.setAvgFh(avg);
                compare.setQyid(areaId);
                compare.setYccj(teamName);
                compare.setYcrq(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()));
                compare.setMaxFh(max);
                compare.setMinFh(min);
                compare.setMaxFhTime(maxTime);
                compare.setMinFhTime(minTime);

                // 查询区域名称
                SoInArea area = soInAreaDao.selectById(areaId);
                if (area != null) {
                    compare.setQyName(area.getCtrlAreaName());
                }

                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                compare.setDataDate(date.format(formatter));
                dayRecords.add(compare);
            }
        }

        return dayRecords;
    }

    @Override
    public void dailyLoadComparison10ExportExcel(HttpServletResponse response, LocalDate startTime, LocalDate endTime, String areaId, Integer loadTypeId, List<Integer> teamIds, String batch) throws IOException {

        List<SoInFhCompare> list = new ArrayList<>();
        // 遍历从 startTime 到 endTime 的每一天
        LocalDate currentDate = startTime;
        while (!currentDate.isAfter(endTime)) {
            // 对每一天执行处理逻辑
            List<SoInFhCompare> dailyRecords = processDay(loadTypeId, currentDate, areaId, teamIds);
            if (!CollectionUtils.isEmpty(dailyRecords)) {
                list.addAll(dailyRecords);
            }
            // 日期递增一天
            currentDate = currentDate.plusDays(1);
        }

        for (SoInFhCompare compare : list) {
            SoInArea area = soInAreaDao.selectById(areaId);
            compare.setQyName(area.getCtrlAreaName());
            Date ycrq = compare.getYcrq();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = sdf.format(ycrq);
            compare.setDataDate(formattedDate);
            //compare.setAccuracy(compare.getAccuracy() * 100);
        }
        ServletOutputStream outputStream = response.getOutputStream();

        try {
            String fileName = UUID.randomUUID().toString();
            //FileUtil.setExcelResponseProp(response, "日负荷对比数据");
            FileUtil.setExcelResponseProp(response, fileName);
            EasyExcel.write(outputStream, FhCompareDTO.class)//对应的导出实体类
                    .excelType(ExcelTypeEnum.XLSX)//excel文件类型，包括CSV、XLS、XLSX
                    .sheet("日负荷对比")//导出sheet页名称
                    .doWrite(list); //查询获取的数据集合List<T>，转成excel
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            outputStream.flush();
            outputStream.close();
        }
    }

    @Override
    public void dailyLoadComparison1ExportExcel(HttpServletResponse response, LocalDate localDate, String areaId, Integer loadTypeId, List<Integer> teamIds, String batch) throws IOException {

        List<SoInFhCompare> records = new ArrayList<>();

        if (!CollectionUtils.isEmpty(teamIds)) {
            for (Integer i : teamIds) {
                QueryWrapper<SoInLoadForecast> forecastWrapper = new QueryWrapper<>();
                double sum = 0.0;
                double max = Double.NEGATIVE_INFINITY;
                //double max = 0.0;
                double min = Double.POSITIVE_INFINITY;
                //double min = 0.0;
                double avg = 0.0;
                Date maxTime = null;
                Date minTime = null;
                int count = 0;
                String teamName = null;
                SoInTeam team = soInTeamDao.selectById(i);
                if (team != null) {
                    teamName = team.getTeamName();
                }
                forecastWrapper.eq("YCCJ", teamName);
                forecastWrapper.eq("QYID", areaId);
                LocalDateTime startOfDay = localDate.atStartOfDay(); // 2024-10-30 00:00:00
                LocalDateTime endOfDay = localDate.atTime(23, 59, 59); // 2024-10-30 23:59:59
                forecastWrapper.ge("YCRQ", startOfDay)
                        .le("YCRQ", endOfDay);
                List<SoInLoadForecast> forecastList = soInFhLoadForecastDao.selectList(forecastWrapper);
                SoInFhCompare compare = new SoInFhCompare();
                SoInArea area = soInAreaDao.selectById(areaId);
                compare.setQyName(area.getCtrlAreaName());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String formattedDate = localDate.format(formatter);
                compare.setDataDate(formattedDate);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                double totalRelativeError = 0.0;
                int errorCount = 0;
                if (loadTypeId == 1) {
                    // 获取当天的实际负荷数据
                    QueryWrapper<SoInLoadInfoXt> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", startOfDay)
                            .le("FHSJ", endOfDay);
                    List<SoInLoadInfoXt> loadInfoList = soInFhLoadInfoXtDao.selectList(infoXtWrapper);
                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;

                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }
                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoXt> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }
                    }


                }
                if (loadTypeId == 2) {
                    QueryWrapper<SoInLoadInfoTd> infoXtWrapper = new QueryWrapper<>();
                    infoXtWrapper.eq("QYID", areaId);
                    infoXtWrapper.ge("FHSJ", startOfDay)
                            .le("FHSJ", endOfDay);
                    List<SoInLoadInfoTd> loadInfoList = soInFhLoadInfoTdDao.selectList(infoXtWrapper);
                    for (SoInLoadForecast forecast : forecastList) {
                        Double ycz = forecast.getYcz();
                        Date ycrq = forecast.getYcrq(); // 预测时间

                        if (ycz == null || ycrq == null) {
                            continue; // 跳过无效数据
                        }

                        sum += ycz;
                        count++;

                        if (ycz > max) {
                            max = ycz;
                            maxTime = ycrq;

                        }

                        if (ycz < min) {
                            min = ycz;
                            minTime = ycrq;
                        }
                        // 匹配相同时间的实际值
                        Optional<SoInLoadInfoTd> actualOpt = loadInfoList.stream()
                                .filter(info -> sdf.format(info.getFhsj()).equals(sdf.format(ycrq)))
                                .findFirst();

                        if (actualOpt.isPresent()) {
                            double actual = actualOpt.get().getFh();
                            double predicted = ycz;
                            if (actual != 0) { // 防止除以零
                                double relativeError = Math.abs((actual - predicted) / actual);
                                totalRelativeError += relativeError;
                                errorCount++;
                            }
                        }


                    }
                }

                if (count > 0) {
                    avg = sum / count;
                    BigDecimal bigDecimal = new BigDecimal(avg);
                    bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP); // 四舍五入
                    avg = bigDecimal.doubleValue();
                } else {
                    avg = 0.0;
                    max = 0.0;
                    min = 0.0;
                }


                compare.setAvgFh(avg);
                // 计算平均准确率
                double accuracyRate = 0.0;
                if (errorCount > 0) {
                    accuracyRate = (1 - (totalRelativeError / errorCount)) * 100;
                    DecimalFormat df = new DecimalFormat("#.00");
                    accuracyRate = Double.parseDouble(df.format(accuracyRate)); // 保留两位小数
                }

                compare.setQyid(areaId);
                compare.setYccj(teamName);
                Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
                compare.setYcrq(date);

                compare.setAccuracy(accuracyRate);

                compare.setMaxFh(max);
                compare.setMinFh(min);
                compare.setMaxFhTime(maxTime);
                compare.setMinFhTime(minTime);
                records.add(compare);
            }

        }
/*        LocalDate today = LocalDate.now(); // 获取今天的日期
        if (localDate.isAfter(today) || localDate.isEqual(today)) {
            for (SoInFhCompare compare : records) {
                SoInArea area = soInAreaDao.selectById(areaId);
                compare.setQyName(area.getCtrlAreaName());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String formattedDate = localDate.format(formatter);
                compare.setDataDate(formattedDate);
                compare.setAccuracy(null);
                compare.setAvgFh(null);
                compare.setMaxFh(null);
                compare.setMaxFhTime(null);
                compare.setMinFh(null);
                compare.setMinFhTime(null);
            }
        }
        if (localDate.isBefore(today)) {
            for (SoInFhCompare compare : records) {
                SoInArea area = soInAreaDao.selectById(areaId);
                compare.setQyName(area.getCtrlAreaName());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String formattedDate = localDate.format(formatter);
                compare.setDataDate(formattedDate);
            }
        }*/


        ServletOutputStream outputStream = response.getOutputStream();
        try {
            String fileName = UUID.randomUUID().toString();
            //FileUtil.setExcelResponseProp(response, "日负荷对比数据");
            FileUtil.setExcelResponseProp(response, fileName);
            EasyExcel.write(outputStream, FhCompareDTO.class)//对应的导出实体类
                    .excelType(ExcelTypeEnum.XLSX)//excel文件类型，包括CSV、XLS、XLSX
                    .sheet("日负荷对比")//导出sheet页名称
                    .doWrite(records); //查询获取的数据集合List<T>，转成excel
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            outputStream.flush();
            outputStream.close();
        }
    }

}
